package com.wxxymaker.edu.service;

import com.blade.ioc.annotation.Bean;
import com.wxxymaker.edu.model.entity.Announcement;
import com.wxxymaker.edu.model.entity.Course;
import com.wxxymaker.edu.model.entity.Task;
import com.wxxymaker.edu.model.entity.User;
import com.wxxymaker.edu.utils.TimeUtils;
import io.github.biezhi.anima.Anima;
import io.github.biezhi.anima.core.AnimaQuery;
import io.github.biezhi.anima.core.Joins;
import io.github.biezhi.anima.enums.OrderBy;
import io.github.biezhi.anima.page.Page;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

import static io.github.biezhi.anima.Anima.select;
import static io.github.biezhi.anima.Anima.update;

/**
 * @author zyx
 * @date 2018/9/14 - 16:37
 * @DESCRIBE 公告Service
 */
@Bean
@Slf4j
public class AnnouncementService implements Service<Announcement> {
    public Announcement add(Announcement announcement) {
        boolean rollback = Anima.atomic(() -> {
            Integer pk = announcement.save().asInt();
            announcement.setId(pk);
        }).catchException(e -> {
            log.error("添加失败{}", e.getMessage());
        }).isRollback();
        return rollback ? null : announcement;
    }

    @Override
    public Announcement delete(Object pk) {
        Announcement announcement = byId(pk);
        boolean rollback = Anima.atomic(announcement::delete)
                .catchException(e -> {
                    log.error("删除失败!{}", e.getMessage());
                }).isRollback();
        return rollback ? null : announcement;
    }

    public boolean deleteByid(Integer id) {
        boolean rollback = Anima.atomic(() -> {
            Anima.delete().from(Announcement.class)
                    .where(Announcement::getId, id)
                    .execute();
        }).catchException(e -> {
            log.error("删除公告失败!{}", e.getMessage());
        }).isRollback();
        return !rollback;
    }

    @Override
    public boolean change(Announcement announcement) {
        return false;
    }

    public Page<Announcement> getByUid(Integer uid, Integer page, Integer size) {
        AnimaQuery<Announcement> from = Anima.select().from(Announcement.class)
                .join(Joins.with(Course.class)
                        .as(Announcement::getCourse)
                        .on(Announcement::getCourseId, Course::getId))
                .notEq(Announcement::getCourseId, -9);
        if (uid > 0) {
            from.where(Announcement::getUserId, uid);
        }
        return from.page(page, size);
    }

    public Page<Announcement> getByKid(Integer kid, Integer page, Integer size) {
        AnimaQuery<Announcement> from = Anima.select().from(Announcement.class)
                .notEq(Announcement::getCourseId, -9)
                .join(Joins.with(Task.class)
                        .as(Announcement::getTask)
                        .on(Announcement::getTaskId, Task::getId))
                .join(Joins.with(Course.class)
                        .as(Announcement::getCourse)
                        .on(Announcement::getCourseId, Course::getId))
                .join(Joins.with(User.class)
                        .as(Announcement::getUser)
                        .on(Announcement::getUserId, User::getId));
        if (kid > 0) {
            from.where(Announcement::getCourseId, kid);
        }
        return from.page(page, size);
    }

    public List<Announcement> getByKid(Integer kid) {
        return select().from(Announcement.class)
                .join(Joins.with(Course.class)
                        .as(Announcement::getCourse)
                        .on(Announcement::getCourseId, Course::getId))
                .join(Joins.with(Task.class)
                        .as(Announcement::getTask)
                        .on(Announcement::getTaskId, Task::getId))
                .where(Announcement::getCourseId, kid)
                .all();
    }

    public Page<Announcement> getByAid(Integer aid) {
        AnimaQuery<Announcement> from = Anima.select().from(Announcement.class)
                .notEq(Announcement::getCourseId, -9)
                .join(Joins.with(Course.class)
                        .as(Announcement::getCourse)
                        .on(Announcement::getCourseId, Course::getId));
        if (aid > 0) {
            from.where(Announcement::getId, aid);
        }
        return from.page(1, 1);
    }

    public Announcement showById(Integer id) {
        return select().from(Announcement.class).byId(id);
    }

    @Override
    public Announcement byId(Object pk) {
        return (select().from(Announcement.class).byId(pk));
    }

    public Integer updateById(Announcement ann) {
        int i = update().from(Announcement.class)
                .set(Announcement::getCourseId, ann.getCourseId())
                .set(Announcement::getTaskId, ann.getTaskId())
                .set(Announcement::getStartTime, ann.getStartTime())
                .set(Announcement::getEndTime, ann.getEndTime())
                .set(Announcement::getContent, ann.getContent())
                .updateById(ann.getId());
        return i;
    }

    public int deleteByKid(Integer kid) {
        return Anima.delete().from(Announcement.class).where(Announcement::getCourseId, kid).execute();
    }

    public Page<Announcement> getSysAnn(int pageNo, int limit, Boolean all) {
        String now = TimeUtils.getDate();
        AnimaQuery<Announcement> where = Anima.select().from(Announcement.class)
                .order(Announcement::getId, OrderBy.DESC)
                .where(Announcement::getCourseId, -9);
        if (!all) {
            where.gte(Announcement::getEndTime, now)
                    .lte(Announcement::getStartTime, now);
        }
        return where.page(pageNo, limit);
    }
}
